package edu.thu.studio.ormdesigner.outline;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;

import edu.thu.studio.ormdesigner.model.ORMModel;
import edu.thu.studio.ormdesigner.outline.action.CreateDomainAction;
import edu.thu.studio.ormdesigner.outline.action.CreateDiagramAction;
import edu.thu.studio.ormdesigner.outline.action.UpdateDomainAction;
import edu.thu.studio.ormdesigner.outline.action.UpdateDiagramAction;
import edu.thu.studio.ormdesigner.outline.editpart.DomainOutlineEditPart;
import edu.thu.studio.ormdesigner.outline.editpart.DomainSetOutlineEditPart;
import edu.thu.studio.ormdesigner.outline.editpart.DiagramOutlineEditPart;
import edu.thu.studio.ormdesigner.outline.editpart.DiagramSetOutlineEditPart;
import edu.thu.studio.ormdesigner.util.Utils;

public class OutlinePopupMenuManager extends MenuManager {
    @SuppressWarnings("rawtypes")
    private static Map<Class, String> ACTION_MAP = new HashMap<Class, String>();
    
    static {
        ACTION_MAP.put(DomainSetOutlineEditPart.class, CreateDomainAction.ID);
        ACTION_MAP.put(DomainOutlineEditPart.class, UpdateDomainAction.ID);
        ACTION_MAP.put(DiagramSetOutlineEditPart.class, CreateDiagramAction.ID);
        ACTION_MAP.put(DiagramOutlineEditPart.class, UpdateDiagramAction.ID);
    }
    
    private ActionRegistry actionRegistry;
    
    private ActionRegistry outlineActionRegistry;
    
    public OutlinePopupMenuManager(final ORMModel model, ActionRegistry actionRegistry,
        ActionRegistry outlineActionRegistry, final EditPartViewer editPartViewer) {
        try {
            this.actionRegistry = actionRegistry;
            this.outlineActionRegistry = outlineActionRegistry;
            
            this.add(this.getAction(CreateDomainAction.ID));
            this.add(this.getAction(UpdateDomainAction.ID));
            
            this.add(new Separator());
            this.add(this.getAction(CreateDiagramAction.ID));
            this.add(this.getAction(UpdateDiagramAction.ID));
            
            this.addMenuListener(new IMenuListener() {
                
                @SuppressWarnings("rawtypes")
                public void menuAboutToShow(IMenuManager manager) {
                    try {
                        List selectedEditParts = editPartViewer.getSelectedEditParts();
                        if (selectedEditParts.isEmpty()) {
                            if (getMenu().isVisible()) {
                                getMenu().setVisible(false);
                            }
                        } else {
                            if (!getMenu().isVisible()) {
                                getMenu().setVisible(true);
                            }
                            EditPart editPart = (EditPart) selectedEditParts.get(0);
                            for (Class clazz : ACTION_MAP.keySet()) {
                                enabled(ACTION_MAP.get(clazz), clazz.isInstance(editPart));
                            }
                        }
                        
                        manager.update(true);
                        
                    } catch (Exception e) {
                        Utils.showExceptionDialog(e);
                    }
                }
                
            });
            
        } catch (Exception e) {
            Utils.showExceptionDialog(e);
        }
    }
    
    private IAction getAction(String id) {
        IAction action = this.actionRegistry.getAction(id);
        
        if (action == null) {
            action = this.outlineActionRegistry.getAction(id);
        }
        
        return action;
    }
    
    private void enabled(String id, boolean enabled) {
        IAction action = getAction(id);
        action.setEnabled(enabled);
    }
    
}
